#include "PDFConverter.h"
#include "GString.h"
#include "GlobalParams.h"
#include "HtmlOutputDev.h"
#include "utf8.h"
#include <cstdlib>
#include <cstring>
#include <boost/filesystem.hpp>

#ifdef _DEBUG
#include <iostream>
#endif

namespace Pdfcon
{
	Converter* objPointer = NULL;

Converter::Converter(void)
{
	myPdf = NULL;
	char cfgFileName[256] = "";
	globalParams = new GlobalParams(cfgFileName);
	globalParams->setTextEncoding("UTF-8");


	myTmpDir = "./tmp_pdf/";
	boost::filesystem::create_directory(myTmpDir);
}

Converter::Converter(std::string theTmpDir)
{
	myPdf = NULL;
	char cfgFileName[256] = "";
	globalParams = new GlobalParams(cfgFileName);
	globalParams->setTextEncoding("UTF-8");
	

	myTmpDir = theTmpDir;
	boost::filesystem::create_directories(myTmpDir);
}


Converter::~Converter(void)
{
	delete myPdf;
	delete globalParams;

	boost::filesystem::remove_all(myTmpDir);
}

bool Converter::Open(PComunicator::PFileInfo &theFile)
{
	//z hladiska moduloveho systemu a charakteru ako sa data zadavaju do systemu
	//convertor nepodporuje moznost prace s heslovanimi pdf subormi.
	GString *pdfOwnerPass = NULL;
	GString *pdfUserPass = NULL;
	Object info;

	mypdfname = theFile.GetFullName();

	theFile.Save(myTmpDir);
	std::string thepath = myTmpDir + theFile.GetFullName();
	GString afile(thepath.c_str());
	myPdf = new PDFDoc(&afile,pdfOwnerPass,pdfUserPass);
	if(!myPdf->isOk())
		return false;
	if(!myPdf->okToCopy())
		return false;

	return true;
}

std::wstring Converter::Read()
{
	char *buffer = new char[100];
	Object info;
	myPdf->getDocInfo(&info);
	MemStream ms(buffer,0,100,&info);

	objPointer = this;
	void (*preader)(void*,char*,int) = &wrapper_reader;
		
	TextOutputDev output(preader,&ms,0,1);
	if(output.isOk())
	{
		myPdf->displayPages(&output,1,myPdf->getNumPages()-1,72,72,0,false,true,false);
		objPointer = NULL;
	}
	delete buffer;
	return myOutput;

}

std::string Converter::CreateHtml(std::string thePath)
{
	if(!boost::filesystem::exists(thePath))
	{
		boost::filesystem::create_directories(thePath);
	}

	thePath += mypdfname;

#ifdef _DEBUG
	std::cout << thePath << std::endl;
#endif

	Object info;
	myPdf->getDocInfo(&info);

	GBool noframes = gTrue;
	GBool complex = gTrue;
	GBool ignore_images = gTrue;
	
	std::string docName = get_info(info.getDict(), "Title");
	info.free();
	
	char *_path = new char[thePath.length()+1];
	char *_doc = new char[docName.length()+1];
	strcpy(_path,thePath.c_str());
	strcpy(_doc,docName.c_str());


	HtmlOutputDev aHtmlDev(_path,_doc,"FEI",NULL,NULL,NULL,"png",gTrue,1,myPdf->getCatalog()->getOutline()->isDict());
	if(aHtmlDev.isOk())
	{
		//myPdf->displayPages(&aHtmlDev,1,myPdf->getNumPages()-1,72,72,0,false,true,false);
		myPdf->displayPages(&aHtmlDev,1,myPdf->getNumPages()-1,72*1.5,72*1.5,0,gTrue,gFalse,gTrue);
		aHtmlDev.dumpDocOutline(myPdf->getCatalog());
	}
	
	mypdfname = thePath;
#ifdef _DEBUG
	std::cout << "returning " << thePath << std::endl;
#endif

	return mypdfname;
}

std::string Converter::Format()
{
	return "pdf";
}

char* Converter::Version()
{
	return "1.0";
}


char* Converter::Autor()
{
	return "Marek Szanyi";
}


//////////////////////////////////////////////////////////////////////////
/*							PRIVATE METHODS								*/
//////////////////////////////////////////////////////////////////////////

void Converter::reader(char *text, int len)
{
	//if(std::isspace(text[0]) != 0)
	//	this->myOutput.append(L" ");
	//else
	//{
		std::string input(text,len);
		std::wstring result;
		utf8::utf8to16(input.begin(),input.end(),std::back_inserter(result));
		this->myOutput +=result;
	//}
}

void Converter::wrapper_reader(void *stream,char *text,int len)
{
	if(Pdfcon::objPointer != NULL)
	{
		objPointer->reader(text,len);
	}
}

std::string Converter::get_info(Dict *infoDict, char *key) 
{
	Object obj;
	std::string result;

	if (infoDict->lookup(key, &obj)->isString()) 
	{
		std::string _result(obj.getString()->getCString(),obj.getString()->getLength());
		result.append(_result);
	}
	obj.free();

	return result;
}

}//end of namespace Pdfcon
